﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint;
using System.Diagnostics;

namespace UserControlFormSolution
{
    public class WebServiceListStoreProcessor : IFormProcessor
    {
        private ListsWS.Lists lists = null;
        private XmlDocument listdoc = null;
        private XmlNamespaceManager nsmgr = null;
        private XmlElement method = null;
        private XmlDocument batchdoc = null;
        private XmlElement batch = null;
        private string listid = null;
        private string listversion = null;
        private string listname = null;
        private string weburl = null;
        private bool enableattachments = false;
        private Dictionary<string, byte[]> attachments = new Dictionary<string, byte[]>();

        #region IFormProcessor Members

        void IFormProcessor.Prepare(string weburl, string listname, string username, string password)
        {
            this.listname = listname;
            this.weburl = weburl;
            lists = new UserControlFormSolution.ListsWS.Lists();
            lists.Credentials = System.Net.CredentialCache.DefaultCredentials;
            if (!string.IsNullOrEmpty(username))
            {
                lists.Credentials = new System.Net.NetworkCredential(username, password);
            }
            lists.Url = SPUrlUtility.CombineUrl(weburl, "_vti_bin/lists.asmx");

            XmlNode listnode = lists.GetList(listname);
            listid = listnode.Attributes["ID"].Value;
            listversion = listnode.Attributes["Version"].Value;
            enableattachments = bool.Parse(listnode.Attributes["EnableAttachments"].Value);
            
            listdoc = new XmlDocument();
            listdoc.LoadXml(listnode.OuterXml);
            nsmgr = new XmlNamespaceManager(listdoc.NameTable);
            nsmgr.AddNamespace("sp", "http://schemas.microsoft.com/sharepoint/soap/");

            batchdoc = new XmlDocument();
            #region Create Batch node
            batch = batchdoc.CreateElement("Batch");
            batch.SetAttribute("OnError", "Continue");
            batch.SetAttribute("ListVersion", "1");
            #endregion

            #region Create Method node
            method = (XmlElement)batch.AppendChild(batchdoc.CreateElement("Method"));
            method.SetAttribute("ID", "1");
            method.SetAttribute("Cmd", "New");
            #endregion

            #region Add ID Field
            XmlElement field = (XmlElement)method.AppendChild(batchdoc.CreateElement("Field"));
            field.SetAttribute("Name", "ID");
            field.InnerText = "New";
            #endregion
        }

        void IFormProcessor.AddField(string fieldname, string value)
        {
            XmlNode fieldnode = listdoc.SelectSingleNode(string.Format("//sp:Field[@Name='{0}']", fieldname), nsmgr);
            if (fieldnode != null)
            {
                string SourceID = null;
                try
                {
                    SourceID = fieldnode.Attributes["SourceID"].Value;
                }
                catch { }
                bool ReadOnly = false;
                try
                {
                    ReadOnly = bool.Parse(fieldnode.Attributes["ReadOnly"].Value);
                }
                catch
                {
                }
                bool Hidden = false;
                try
                {
                    Hidden = bool.Parse(fieldnode.Attributes["Hidden"].Value);
                }
                catch
                {
                }
                string FieldID = null;
                try
                {
                    FieldID = fieldnode.Attributes["ID"].Value;
                }
                catch { }
                if (!Hidden && !ReadOnly && !string.IsNullOrEmpty(FieldID))
                {
                    string FieldType = fieldnode.Attributes["Type"].Value;
                    string FieldName = fieldnode.Attributes["Name"].Value;
                    if (FieldType == "Text")
                    {
                        XmlElement field = (XmlElement)method.AppendChild(batchdoc.CreateElement("Field"));
                        field.SetAttribute("Name", FieldName);
                        field.InnerText = value;
                    }
                }

            }
        }

        void IFormProcessor.AddAttachment(string filename, byte[] attachment)
        {

            if (enableattachments)
            {
                attachments.Add(filename, attachment);
            }
            else
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    EventLog.WriteEntry(this.GetType().FullName, string.Format("The List \"{0}\" of Web \"{1}\" has disabled attachments.", listname , weburl ), EventLogEntryType.Warning );
                });
            }
        }

        void IFormProcessor.Finish()
        {
            try
            {
                XmlNode updateresultnode = lists.UpdateListItems(listid, batch);
                string listitemid = updateresultnode.SelectSingleNode("//@ows_ID").Value;
                foreach (KeyValuePair<string, byte[]> pair in attachments)
                {
                    string attachmenturl = lists.AddAttachment(listname, listitemid, pair.Key, pair.Value);
                }
            }
            catch (Exception ex)
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    EventLog.WriteEntry(this.GetType().FullName, string.Format("Unable to add a item to the List \"{0}\" of Web \"{1}\"."+Environment.NewLine+ex.ToString(), listname, weburl), EventLogEntryType.Error);
                });
                throw;
            }
        }

        #endregion
    }
}
